JWT (JSON Web Token):
JSON Web Token (JWT) একটি কমপ্যাক্ট এবং সুরক্ষিত টোকেন ফরম্যাট যা JSON-ভিত্তিক ডেটা এনকোড করে একটি সাইনড স্ট্রিং আকারে আদান-প্রদান করা হয়। এটি সাধারণত অ্যাপ্লিকেশনগুলোর Authentication এবং Authorization এর জন্য ব্যবহৃত হয়।
JWT কেন ব্যবহৃত হয়?
JWT প্রধানত নিম্নলিখিত কারণগুলোতে ব্যবহৃত হয়:
- Stateless Authentication:
- JWT ব্যবহার করে সার্ভারকে ক্লায়েন্টের সেশন সংরক্ষণ করতে হয় না।
- টোকেনটি নিজেই সমস্ত তথ্য বহন করে যা সেশন পরিচালনার জন্য প্রয়োজন।
- Self-Contained Token:
- JWT একটি Self-Contained Token যা ব্যবহারকারী সম্পর্কিত সমস্ত তথ্য এনকোড করা থাকে।
- Cross-Domain Communication:
- এটি ওয়েব ব্রাউজার এবং API-এর মধ্যে সহজে কাজ করে।
- Cross-Origin Resource Sharing (CORS) সমস্যার সমাধানে সাহায্য করে।
- Compact and Efficient:
- JSON ভিত্তিক ডেটা সংরক্ষণ করে যা Human-Readable এবং Lightweight।
- HTTP Header, Query Parameter, বা Cookie এর মাধ্যমে সহজেই পাঠানো যায়।
- Security:
- টোকেনটি ডিজিটালি সাইনড থাকে (HMAC বা RSA), যা নিশ্চিত করে যে এটি পরিবর্তিত হয়নি।
- JWT এনক্রিপশন ব্যবহার করলে ডেটা এনক্রিপ্টেড ফরম্যাটে থাকে।
JWT এর স্ট্রাকচার:
JWT তিনটি অংশে বিভক্ত থাকে এবং প্রতিটি অংশ ডট (.) দিয়ে পৃথক করা হয়:
HEADER.PAYLOAD.SIGNATURE
- Header:
- Header-এ টোকেনের প্রকার এবং সাইনিং অ্যালগরিদমের তথ্য থাকে।
উদাহরণ:
{ "alg": "HS256", "typ": "JWT" }
- Payload:
- Payload-এ টোকেনের মূল তথ্য (Claims) থাকে।
উদাহরণ:
{ "sub": "1234567890", "name": "John Doe", "role": "ADMIN", "exp": 1688000000 }
- Signature:
- Signature টোকেনের স্বাক্ষর যা হেডার, পে-লোড এবং সিক্রেট কী ব্যবহার করে জেনারেট করা হয়।
উদাহরণ:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secretKey )
JWT এর কাজ করার ধাপ:
- User Authentication:
- ব্যবহারকারী লগইন করলে সার্ভার তার পরিচয় যাচাই করে।
- যাচাই সফল হলে, সার্ভার একটি JWT জেনারেট করে এবং ক্লায়েন্টকে প্রদান করে।
- Client Stores Token:
- ক্লায়েন্ট এই JWT টোকেনটি স্থানীয় স্টোরেজ বা কুকিতে সংরক্ষণ করে।
- Token Usage:
ক্লায়েন্ট পরবর্তী API রিকোয়েস্টের সাথে
Authorizationহেডারে JWT পাঠায়:Authorization: Bearer <JWT_TOKEN>
- Server Validates Token:
- সার্ভার প্রাপ্ত টোকেনটি যাচাই করে।
- যদি টোকেন বৈধ হয়, তাহলে ক্লায়েন্টকে রিসোর্স অ্যাক্সেস করতে দেয়।
JWT এর সুবিধা:
- Stateless:
- সার্ভার সেশনের জন্য কোনো স্টোরেজ বা ডাটাবেসের প্রয়োজন নেই।
- Performance:
- সার্ভারের লোড কমিয়ে দ্রুত অ্যাক্সেস নিশ্চিত করে।
- Scalability:
- ক্লাস্টার বা ডিস্ট্রিবিউটেড সিস্টেমে কাজ করতে সহজ।
- Cross-Platform Compatibility:
- ভিন্ন ভিন্ন টেকনোলজির মধ্যে কাজ করার জন্য উপযুক্ত।
JWT এর সীমাবদ্ধতা:
- Token Revocation:
- JWT স্টেটলেস হওয়ায় এটি অবৈধ (revoke) করা কঠিন।
- Token Size:
- JWT সেশন কুকির চেয়ে বড় হতে পারে, যা কিছু ক্ষেত্রে বেশি ব্যান্ডউইথ ব্যবহার করতে পারে।
- Expiration Management:
- টোকেন মেয়াদ শেষ হওয়ার পরে নতুন টোকেন জেনারেট করতে ক্লায়েন্টের অতিরিক্ত কাজ করতে হয়।
Spring Security-তে JWT এর ব্যবহার:
Step 1: ডিপেনডেন্সি যোগ করুন
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
Step 2: JWT Token Generator তৈরি করুন
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtil {
private static final String SECRET_KEY = "secretKey";
public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1 hour validity
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public static boolean validateToken(String token, String username) {
String extractedUsername = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
return extractedUsername.equals(username) && !isTokenExpired(token);
}
private static boolean isTokenExpired(String token) {
Date expiration = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getExpiration();
return expiration.before(new Date());
}
}
Step 3: JWT Filter তৈরি করুন
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JwtFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
String token = authorizationHeader.substring(7);
String username = JwtUtil.extractUsername(token);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
if (JwtUtil.validateToken(token, username)) {
Authentication auth = JwtUtil.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
}
filterChain.doFilter(request, response);
}
}
Step 4: Spring Security Config এ JWT যুক্ত করুন
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtFilter());
}
}
JWT এর জন্য সেরা চর্চা (Best Practices):
- Short Token Expiry:
- টোকেনের মেয়াদ সংক্ষিপ্ত রাখুন এবং রিফ্রেশ টোকেন ব্যবহার করুন।
- Secure Secret Key:
- একটি শক্তিশালী এবং নিরাপদ সিক্রেট কী ব্যবহার করুন।
- HTTPS ব্যবহার:
- সমস্ত টোকেন এনক্রিপ্টেড ট্র্যাফিকে (HTTPS) পাঠান।
- Revocation Mechanism:
- ব্ল্যাকলিস্ট বা কনকারেন্ট সেশন কন্ট্রোল ইমপ্লিমেন্ট করুন।
উপসংহার:
JWT একটি লাইটওয়েট এবং কার্যকর সল্যুশন যা অ্যাপ্লিকেশনগুলিতে Stateless Authentication নিশ্চিত করে। এটি বিশেষত মাইক্রোসার্ভিস এবং মোবাইল অ্যাপ্লিকেশনের মতো ডিস্ট্রিবিউটেড সিস্টেমের জন্য উপযুক্ত। Spring Security-তে JWT সহজেই ইমপ্লিমেন্ট করা যায়, যা Authentication এবং Authorization এর জন্য একটি আধুনিক এবং নিরাপদ সমাধান প্রদান করে।
Read more